package com.example.shuiyin.security;

import com.example.shuiyin.config.JwtProperties;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;

@Slf4j
public class JwtTokenProvider {
    
    private final JwtProperties jwtProperties;
    private SecretKey secretKey;
    
    public JwtTokenProvider(JwtProperties jwtProperties) {
        log.info("开始初始化JwtTokenProvider");
        this.jwtProperties = jwtProperties;
        
        // 记录配置信息
        log.info("JWT配置: secret={}, expiration={}", 
                StringUtils.hasLength(jwtProperties.getSecret()) ? "[已配置]" : "[未配置]", 
                jwtProperties.getExpiration());
        
        // 初始化密钥
        try {
            if (jwtProperties == null || !StringUtils.hasLength(jwtProperties.getSecret())) {
                throw new IllegalStateException("JWT密钥未配置，请检查application.properties中的jwt.secret属性");
            }
            
            initializeSecretKey();
            log.info("JWT密钥初始化成功");
        } catch (Exception e) {
            log.error("JWT密钥初始化失败: {}", e.getMessage(), e);
            // 不抛出异常，使用默认密钥，确保应用能启动
            try {
                // 使用默认密钥
                String defaultSecret = "shuiyinappsecretkey12345678901234567890";
                byte[] keyBytes = defaultSecret.getBytes(StandardCharsets.UTF_8);
                this.secretKey = Keys.hmacShaKeyFor(keyBytes);
                log.warn("使用默认JWT密钥，建议在生产环境中配置自定义密钥");
            } catch (Exception ex) {
                log.error("使用默认JWT密钥失败: {}", ex.getMessage(), ex);
            }
        }
    }
    
    private void initializeSecretKey() {
        // 确保默认值可用
        String secret = "shuiyinappsecretkey12345678901234567890";
        
        // 如果配置中有值，则使用配置值
        if (jwtProperties != null && StringUtils.hasLength(jwtProperties.getSecret())) {
            secret = jwtProperties.getSecret();
        }
        
        byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
        this.secretKey = Keys.hmacShaKeyFor(keyBytes);
    }

    /**
     * 获取当前使用的JWT密钥
     * @return JWT密钥
     */
    public SecretKey getSecretKey() {
        if (secretKey == null) {
            initializeSecretKey();
        }
        return secretKey;
    }

    public String generateToken(String userId) {
        Date now = new Date();
        long expirationTime = 86400000L; // 默认1天
        
        if (jwtProperties != null && jwtProperties.getExpiration() != null) {
            expirationTime = jwtProperties.getExpiration();
        }
        
        Date expiryDate = new Date(now.getTime() + expirationTime);
        
        return Jwts.builder()
                .setSubject(userId)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(getSecretKey())
                .compact();
    }

    public String getUserIdFromToken(String token) {
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(getSecretKey())
                .build()
                .parseClaimsJws(token)
                .getBody();

        return claims.getSubject();
    }
    
    public Claims getClaims(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSecretKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    public boolean validateToken(String token) {
        if (!StringUtils.hasLength(token)) {
            return false;
        }
        
        try {
            Jwts.parserBuilder()
                .setSigningKey(getSecretKey())
                .build()
                .parseClaimsJws(token);
            return true;
        } catch (SecurityException ex) {
            log.error("无效的JWT签名");
            return false;
        } catch (MalformedJwtException ex) {
            log.error("无效的JWT令牌");
            return false;
        } catch (ExpiredJwtException ex) {
            log.error("过期的JWT令牌");
            return false;
        } catch (UnsupportedJwtException ex) {
            log.error("不支持的JWT令牌");
            return false;
        } catch (IllegalArgumentException ex) {
            log.error("JWT声明字符串为空");
            return false;
        } catch (Exception ex) {
            log.error("JWT验证异常: {}", ex.getMessage());
            return false;
        }
    }
} 